/*
 *-----------------------------------------------------------------------
 *	AUX.C
 *	This module contains auxiliary procedures called from
 *	main.c
 *-----------------------------------------------------------------------
 */
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

extern int 	npoints, bx, by, total_time, update_time, iterations;
extern HEAP 	*myheap;	/* declared in heap.c */
extern CELL 	*headC;
extern CELL 	*zedC;
extern int 	nCellsType[HOW_MANY_TYPES];
extern double	minForce, maxForce; /* declared in relax.c */

/*
 *----------------------------------------------------------------------
 *	This function actually does the simulation. It does basically
 *	one thing: handles the events in the queue.
 *----------------------------------------------------------------------
 */
void simulation(void)
{
  EVENT *a;
  float time, deltaTime;
  int countIterations = 0;
  double minF, maxF;

  // iterations: N of relaxation steps between 2 time steps
  deltaTime = 1.0 / (float)iterations;
  time = 0.0;
  minF = minForce;
  maxF = maxForce;

  /* fprintf( stderr, "Force min = %f max = %f\n", minForce, maxForce ); */

  // Main loop of simulation
  while( time < (float) total_time)
  {
     a = HeapRemove(myheap);
     while( time < a->eventTime && time < (float) total_time )
     {
        relaxation( 1 );
        time += deltaTime;
        countIterations++;
        /*
         * The notion of one day here is given by
         * the variable 'countIterations'. Every time
         * we reached that count a 'day' has passed
         */
        if ( countIterations == iterations )
        {
           countIterations = 0;	/* reset the loop counter */
           fprintf( stderr, "Current day is %f \n", time );
           if ( minF != minForce || maxF != maxForce )
           {
              /* fprintf( stderr, "Force min = %f max = %f\n", minForce, maxForce ); */
              minF = minForce;
              maxF = maxForce;
           }
        }
     }
     handle_split( a->info );
  }
  /* fprintf( stderr, "Force min = %f max = %f\n", minForce, maxForce ); */
  printf("\n");
  /*
   * The simulation has ended. We can clear the heap.
   * There might be SPLIT events
   */
  myheap = ClearHeap(myheap);
}

/*	
 *-------------------------------------------------------------------------
 *	This function writes the output file in non-interactive mode
 *------------------------------------------------------------------------
 */
void writeOutputFile(OUTFILEMODE mode, char *psFileName, char *intFileName)
{
  switch(mode){

      case PS:
        handles_output_file(psFileName,PS);
        break;

      case INTERNAL:
        handles_output_file(intFileName,INTERNAL);
        break;

      case BOTH:
        handles_output_file(intFileName,INTERNAL);
        fprintf(stderr, "Ignoring PS output file writing...\n");
        //handles_output_file(psFileName,PS);
        break;

      default:
        break;
  }
}	

/*
 *------------------------------------------------------------------------
 *	mode = EXTERNAL -> experiment file
 *	else "creates the cells"
 *------------------------------------------------------------------------
 */
void initing(INMODE mode, char *inp)
{

  print_info();
  
  free_cells_list();
  free_buckets_list(bx,by);
  
  if( mode == EXTERNAL)
     handles_input_file( inp );
  else
     // Cria as células iniciais baseadas nas probabilidades de ortcell
     makes_all_cells();
  printf("Initial number of cells = %d\n", npoints );
  printf("By type:\n");
  printf("C = %d D = %d E = %d F = %d\n",
	 nCellsType[C],
	 nCellsType[D],
	 nCellsType[E],
	 nCellsType[F]);

  assign_buckets();
  
  /* if the cells were not read from an
     experiment file, we have to relax the newly
     created cells */
  if(mode != EXTERNAL)
     set_up();
  
  /*update_relax_events_queue(0, update_time);*/
  update_split_events_queue();
}

void exiting()
{

  printf("Final number of cells = %d\n",npoints);
  printf("By type:\n");
  printf("C = %d D = %d E = %d F = %d\n",nCellsType[C],
	 nCellsType[D],nCellsType[E],nCellsType[F]);
  
  freeVoronoiSpace();
  free_cells_list();
  
  exit( EXIT_SUCCESS );
}
